using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Data;

namespace SumerCoreDevOps.Infrastructure.BuildTracking;

/// <summary>
/// 构建历史管理器
/// </summary>
public class BuildHistoryManager
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly ILogger<BuildHistoryManager> _logger;

    public BuildHistoryManager(FreeSQLProvider dbProvider, ILogger<BuildHistoryManager> logger)
    {
        _dbProvider = dbProvider;
        _logger = logger;
    }

    /// <summary>
    /// 创建构建历史记录
    /// </summary>
    public async Task<BuildHistory> CreateBuildHistoryAsync(
        long pipelineInstanceId,
        string? gitTag,
        string commitSha,
        string? branchName,
        string triggerType,
        string? triggerUser,
        string? executeNodeId,
        string? buildLanguage,
        string? environment)
    {
        var history = new BuildHistory
        {
            PipelineInstanceId = pipelineInstanceId,
            GitTag = gitTag,
            CommitSha = commitSha,
            CommitShortSha = commitSha.Length > 8 ? commitSha[..8] : commitSha,
            BranchName = branchName,
            TriggerType = triggerType,
            TriggerUser = triggerUser,
            ExecuteNodeId = executeNodeId,
            BuildLanguage = buildLanguage,
            Environment = environment,
            BuildStatus = "Building",
            StartTime = DateTime.UtcNow,
            CreatedAt = DateTime.UtcNow
        };

        await _dbProvider.Orm.Insert(history).ExecuteAffrowsAsync();
        _logger.LogInformation("创建构建历史记录: PipelineInstanceId={PipelineInstanceId}, CommitSha={CommitSha}",
            pipelineInstanceId, commitSha);

        return history;
    }

    /// <summary>
    /// 更新构建历史（完成构建）
    /// </summary>
    public async Task UpdateBuildHistoryAsync(
        long id,
        string buildStatus,
        string? dockerImageTag = null,
        string? imageDigest = null,
        long? imageSize = null,
        string? artifactPath = null,
        string? deploymentVersion = null,
        string? metadata = null)
    {
        var history = await _dbProvider.Orm.Select<BuildHistory>()
            .Where(h => h.Id == id)
            .FirstAsync();

        if (history == null)
        {
            throw new InvalidOperationException($"构建历史记录 {id} 不存在");
        }

        history.BuildStatus = buildStatus;
        history.DockerImageTag = dockerImageTag;
        history.ImageDigest = imageDigest;
        history.ImageSize = imageSize;
        history.ArtifactPath = artifactPath;
        history.DeploymentVersion = deploymentVersion;
        history.Metadata = metadata;
        history.EndTime = DateTime.UtcNow;
        history.DurationSeconds = (int)(history.EndTime.Value - history.StartTime).TotalSeconds;

        await _dbProvider.Orm.Update<BuildHistory>()
            .SetSource(history)
            .ExecuteAffrowsAsync();

        _logger.LogInformation("更新构建历史记录: {Id}, 状态: {Status}", id, buildStatus);
    }

    /// <summary>
    /// 根据流水线实例 ID 获取构建历史
    /// </summary>
    public async Task<BuildHistory?> GetBuildHistoryByPipelineInstanceIdAsync(long pipelineInstanceId)
    {
        return await _dbProvider.Orm.Select<BuildHistory>()
            .Where(h => h.PipelineInstanceId == pipelineInstanceId)
            .FirstAsync();
    }

    /// <summary>
    /// 根据 Git Tag 获取构建历史列表
    /// </summary>
    public async Task<List<BuildHistory>> GetBuildHistoriesByGitTagAsync(string gitTag)
    {
        return await _dbProvider.Orm.Select<BuildHistory>()
            .Where(h => h.GitTag == gitTag)
            .OrderByDescending(h => h.CreatedAt)
            .ToListAsync();
    }

    /// <summary>
    /// 根据 Commit SHA 获取构建历史
    /// </summary>
    public async Task<List<BuildHistory>> GetBuildHistoriesByCommitShaAsync(string commitSha)
    {
        return await _dbProvider.Orm.Select<BuildHistory>()
            .Where(h => h.CommitSha == commitSha)
            .OrderByDescending(h => h.CreatedAt)
            .ToListAsync();
    }

    /// <summary>
    /// 获取最近的构建历史
    /// </summary>
    public async Task<List<BuildHistory>> GetRecentBuildHistoriesAsync(int limit = 50)
    {
        return await _dbProvider.Orm.Select<BuildHistory>()
            .OrderByDescending(h => h.CreatedAt)
            .Limit(limit)
            .ToListAsync();
    }

    /// <summary>
    /// 根据镜像标签获取构建历史
    /// </summary>
    public async Task<BuildHistory?> GetBuildHistoryByImageTagAsync(string imageTag)
    {
        return await _dbProvider.Orm.Select<BuildHistory>()
            .Where(h => h.DockerImageTag == imageTag)
            .FirstAsync();
    }

    /// <summary>
    /// 获取构建统计信息
    /// </summary>
    public async Task<BuildStatistics> GetBuildStatisticsAsync(DateTime? startDate = null, DateTime? endDate = null)
    {
        var query = _dbProvider.Orm.Select<BuildHistory>();

        if (startDate.HasValue)
        {
            query = query.Where(h => h.CreatedAt >= startDate.Value);
        }

        if (endDate.HasValue)
        {
            query = query.Where(h => h.CreatedAt <= endDate.Value);
        }

        var histories = await query.ToListAsync();

        return new BuildStatistics
        {
            TotalBuilds = histories.Count,
            SuccessfulBuilds = histories.Count(h => h.BuildStatus == "Success"),
            FailedBuilds = histories.Count(h => h.BuildStatus == "Failed"),
            CancelledBuilds = histories.Count(h => h.BuildStatus == "Cancelled"),
            AverageDurationSeconds = histories.Where(h => h.DurationSeconds.HasValue)
                .Average(h => h.DurationSeconds ?? 0),
            TotalImageSize = histories.Sum(h => h.ImageSize ?? 0)
        };
    }
}

/// <summary>
/// 构建统计信息
/// </summary>
public class BuildStatistics
{
    public int TotalBuilds { get; set; }
    public int SuccessfulBuilds { get; set; }
    public int FailedBuilds { get; set; }
    public int CancelledBuilds { get; set; }
    public double AverageDurationSeconds { get; set; }
    public long TotalImageSize { get; set; }
}
